/**
 * 角色管理页面逻辑
 *
 * @版权所有 rem.studio
 */
import React, { PureComponent, Fragment } from 'react';
import { formatMessage } from 'umi-plugin-react/locale';
import { connect } from 'dva';
import moment from 'moment';
import {
  Row,
  Col,
  Card,
  Form,
  Input,
  Select,
  Button,
  Modal,
  message,
  Divider,
  Radio,
  Popconfirm,
  Tree,
  Icon,
} from 'antd';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import { saveAs } from 'file-saver';
import ProTable from '@ant-design/pro-table';

import styles from './Admin.less';

const FormItem = Form.Item;
const { Option } = Select;
const { TreeNode } = Tree;
const RadioGroup = Radio.Group;
const InputGroup = Input.Group;
const getValue = obj =>
  Object.keys(obj)
    .map(key => obj[key])
    .join(',');

const CreateForm = Form.create()(props => {
  const { modalVisible, form, handleAdd, handleModalVisible } = props;
  const okHandle = () => {
    form.validateFields((err, fieldsValue) => {
      if (err) return;
      form.resetFields();
      handleAdd(fieldsValue);
    });
  };
  console.log(styles);
  return (
    <Modal
      destroyOnClose
      title={formatMessage({ id: 'app.sysrole.add-role' })}
      visible={modalVisible}
      onOk={okHandle}
      onCancel={() => handleModalVisible()}
    >
      <FormItem
        labelCol={{ span: 6 }}
        wrapperCol={{ span: 15 }}
        label={formatMessage({ id: 'app.sysrole.role-code' })}
      >
        {form.getFieldDecorator('roleCode', {
          rules: [
            {
              required: true,
              message: formatMessage({ id: 'validation.role-code.required' }),
            },
            {
              message: formatMessage({ id: 'validation.role-code.length' }),
              max: 32,
            },
          ],
        })(<Input placeholder={formatMessage({ id: 'app.common.enter' })} />)}
      </FormItem>
      <FormItem
        labelCol={{ span: 6 }}
        wrapperCol={{ span: 15 }}
        label={formatMessage({ id: 'app.sysrole.role-name' })}
      >
        {form.getFieldDecorator('roleName', {
          rules: [
            {
              required: true,
              message: formatMessage({ id: 'validation.role-name.required' }),
            },
            {
              message: formatMessage({ id: 'validation.role-name.length' }),
              max: 64,
            },
          ],
        })(<Input placeholder={formatMessage({ id: 'app.common.enter' })} />)}
      </FormItem>
      <FormItem
        labelCol={{ span: 6 }}
        wrapperCol={{ span: 15 }}
        label={formatMessage({ id: 'app.sysrole.role-description' })}
      >
        {form.getFieldDecorator('roleDescription', {
          rules: [
            {
              message: formatMessage({ id: 'validation.role-description.length' }),
              max: 256,
            },
          ],
        })(<Input.TextArea placeholder={formatMessage({ id: 'app.common.enter' })} />)}
      </FormItem>
    </Modal>
  );
});

@Form.create()
class UpdateForm extends PureComponent {
  static defaultProps = {
    handleUpdate: () => { },
    handleUpdateModalVisible: () => { },
    values: {},
  };

  constructor(props) {
    super(props);

    this.state = {
      formVals: {
        roleCode: props.values.roleCode,
        roleName: props.values.roleName,
        roleDescription: props.values.roleDescription,
        id: props.values.id,
      },
    };

    this.formLayout = {
      labelCol: { span: 6 },
      wrapperCol: { span: 15 },
    };
  }

  renderContent = formVals => {
    const { form } = this.props;

    return [
      <FormItem
        key="roleCode"
        {...this.formLayout}
        label={formatMessage({ id: 'app.sysrole.role-code' })}
      >
        {form.getFieldDecorator('roleCode', {
          rules: [
            {
              required: true,
            },
          ],
          initialValue: formVals.roleCode,
        })(<Input disabled placeholder={formatMessage({ id: 'app.common.enter' })} />)}
      </FormItem>,
      <FormItem
        key="roleName"
        {...this.formLayout}
        label={formatMessage({ id: 'app.sysrole.role-name' })}
      >
        {form.getFieldDecorator('roleName', {
          rules: [
            {
              required: true,
              message: formatMessage({ id: 'validation.role-name.required' }),
            },
            {
              message: formatMessage({ id: 'validation.role-name.length' }),
              max: 64,
            },
          ],
          initialValue: formVals.roleName,
        })(<Input placeholder={formatMessage({ id: 'app.common.enter' })} />)}
      </FormItem>,
      <FormItem
        key="roleDescription"
        {...this.formLayout}
        label={formatMessage({ id: 'app.sysrole.role-description' })}
      >
        {form.getFieldDecorator('roleDescription', {
          rules: [
            {
              message: formatMessage({ id: 'validation.role-description.length' }),
              max: 256,
            },
          ],
          initialValue: formVals.roleDescription,
        })(<Input.TextArea placeholder={formatMessage({ id: 'app.common.enter' })} />)}
      </FormItem>,
    ];
  };

  render() {
    const { updateModalVisible, handleUpdateModalVisible, values } = this.props;
    const { formVals } = this.state;
    const okUpdateHandle = () => {
      const { form, handleUpdate } = this.props;
      const { formVals: oldValue } = this.state;
      form.validateFields((err, fieldsValue) => {
        if (err) return;
        const formVals = { ...oldValue, ...fieldsValue };
        this.setState(
          {
            formVals,
          },
          () => {
            handleUpdate(formVals);
          }
        );
      });
    };

    return (
      <Modal
        destroyOnClose
        title={formatMessage({ id: 'app.sysrole.edit-role' })}
        visible={updateModalVisible}
        onOk={okUpdateHandle}
        onCancel={() => handleUpdateModalVisible(false, values)}
        afterClose={() => handleUpdateModalVisible()}
      >
        {this.renderContent(formVals)}
      </Modal>
    );
  }
}

@Form.create()
class AuthorizeMenuForm extends PureComponent {
  static defaultProps = {
    handleAuthorizeMenu: () => { },
    handleAuthorizeMenuModalVisible: () => { },
    values: {},
  };

  constructor(props) {
    super(props);
    this.state = {
      checkedMenuKeys: props.checkedMenuKeys,
    };
  }

  onCheck = checkedMenuKeys => {
    this.setState({ checkedMenuKeys });
  };
  renderTreeNodes = data => {
    data.map(item => {
      if (item.children) {
        return (
          <TreeNode title={item.title} key={item.key} dataRef={item}>
            {this.renderTreeNodes(item.children)}
          </TreeNode>
        );
      }
      return <TreeNode key={item.key} {...item} />;
    });
  }

  render() {
    const {
      authorizeMenuModalVisible,
      handleAuthorizeMenuModalVisible,
      handleAuthorizeMenu,
      values,
      menuData,
    } = this.props;
    const okAuthorizeHandle = () => {
      handleAuthorizeMenu(values.id, this.state.checkedMenuKeys);
    };

    return (
      <Modal
        destroyOnClose
        title={formatMessage({ id: 'app.sysrole.authorize-menu' })}
        visible={authorizeMenuModalVisible}
        onOk={okAuthorizeHandle}
        onCancel={() => handleAuthorizeMenuModalVisible(false, values)}
        afterClose={() => handleAuthorizeMenuModalVisible()}
      >

        <Tree treeData={menuData} checkable checkedKeys={this.state.checkedMenuKeys} defaultExpandAll onCheck={this.onCheck} selectable={false}>

        </Tree>
        {/* <Tree
          checkable
          selectable={false}
          style={{ width: '100%' }}
          checkedKeys={this.state.checkedMenuKeys}
          onCheck={this.onCheck}
        >
          {menuData ? this.renderTreeNodes(menuData) : []}
        </Tree> */}
      </Modal>
    );
  }
}

//授权按钮弹框
@Form.create()
class AuthorizeMenuButtonForm extends PureComponent {
  static defaultProps = {
    handleAuthorizeMenuButton: () => { },
    handleAuthorizeButtonModalVisible: () => { },
    values: {},
  };

  constructor(props) {
    super(props);
    this.state = {
      checkedMenuButtonKeys: props.checkedMenuButtonKeys,
    };
  }

  onCheck = checkedMenuButtonKeys => {
    this.setState({ checkedMenuButtonKeys });
  };

  renderTreeNodes = data => {
    data.map(item => {
      if (item.children) {
        return (
          <TreeNode title={item.title} key={item.key} dataRef={item}>
            {this.renderTreeNodes(item.children)}
          </TreeNode>
        );
      }
      return <TreeNode key={item.key} {...item} />;
    });
  }


  render() {
    const {
      authorizeMenuButtonModalVisible,
      handleAuthorizeButtonModalVisible,
      handleAuthorizeMenuButton,
      values,
      menuButtonData,
    } = this.props;
    const okAuthorizeButtonHandle = () => {
      handleAuthorizeMenuButton(values.roleCode, this.state.checkedMenuButtonKeys);
    };

    return (
      <Modal
        destroyOnClose
        title={
          <span style={{ color: 'red' }}>
            {formatMessage({ id: 'app.sysrole.authorize-buttontip' })}
          </span>
        }
        visible={authorizeMenuButtonModalVisible}
        onOk={okAuthorizeButtonHandle}
        onCancel={() => handleAuthorizeButtonModalVisible(false, values)}
        afterClose={() => handleAuthorizeButtonModalVisible()}
      >
        {/* <Tree
          checkable
          selectable={false}
          style={{ width: '100%' }}
          checkedKeys={this.state.checkedMenuButtonKeys}
          onCheck={this.onCheck}
        >
          {menuButtonData ? this.renderTreeNodes(menuButtonData) : []}
        </Tree> */}

        <Tree treeData={menuButtonData} checkable checkedKeys={this.state.checkedMenuButtonKeys} defaultExpandAll onCheck={this.onCheck} selectable={false}>

        </Tree>
      </Modal>
    );
  }
}

/* eslint react/no-multi-comp:0 */
@connect(({ sysRole, loading }) => ({
  sysRole,
  loading: loading.models.sysRole,
}))
@Form.create()
class SysRole extends PureComponent {
  state = {
    modalVisible: false,
    updateModalVisible: false,
    authorizeMenuModalVisible: false,
    authorizeMenuButtonModalVisible: false,
    selectedRows: [],
    formValues: {},
    updateFormValues: {},
    menuData: {},
    checkedMenuKeys: [],
    checkedMenuButtonKeys: [],
    hiddenMenuButton: localStorage.getItem('cancersystem_menubutton'),
  };

  columns = [
    {
      title: formatMessage({ id: 'app.sysrole.role-code' }),
      dataIndex: 'roleCode',
    },
    {
      title: formatMessage({ id: 'app.sysrole.role-name' }),
      copyable: true,
      ellipsis: true,
      dataIndex: 'roleName',
    },
    {
      title: formatMessage({ id: 'app.sysrole.role-description' }),
      dataIndex: 'roleDescription',
    },
    {
      title: formatMessage({ id: 'app.common.create-time' }),
      dataIndex: 'createTime',
      sorter: true,
      render: val => <span>{moment(val).format('YYYY-MM-DD HH:mm:ss')}</span>,
    },
    {
      title: formatMessage({ id: 'app.common.operate' }),
      align: 'center',
      render: (text, record) => (
        <Fragment>
          {this.state.hiddenMenuButton.indexOf('sysrole:update') !== -1 ? null : (
            <a onClick={() => this.handleUpdateModalVisible(true, record)}>
              <Icon type="edit" />
              {formatMessage({ id: 'app.common.edit' })}
            </a>
          )}
          <Divider type="vertical" />
          <Popconfirm
            title={formatMessage({ id: 'app.common.confirm-delete' })}
            onConfirm={() => this.deleteItem(record.id)}
          >
            {this.state.hiddenMenuButton.indexOf('sysrole:delete') !== -1 ? null : (
              <a>
                <Icon type="delete" />
                {formatMessage({ id: 'app.common.delete' })}
              </a>
            )}
          </Popconfirm>
          <br />
          <a onClick={() => this.handleAuthorizeMenuFetch(record)}>
            <Icon type="safety-certificate" />
            {formatMessage({ id: 'app.sysrole.authorize-menu' })}
          </a>
          <Divider type="vertical" />
          <a onClick={() => this.handleAuthorizeMenuButtonFetch(record)}>
            <Icon type="safety-certificate" />
            {formatMessage({ id: 'app.sysrole.authorize-button' })}
          </a>
        </Fragment>
      ),
    },
  ];

  componentDidMount() {
    const { dispatch } = this.props;
    dispatch({
      type: 'sysRole/fetch',
    });
  }

  handleBasicTableChange = (pagination, filtersArg, sorter) => {
    const { dispatch } = this.props;
    const { formValues } = this.state;

    const filters = Object.keys(filtersArg).reduce((obj, key) => {
      const newObj = { ...obj };
      newObj[key] = getValue(filtersArg[key]);
      return newObj;
    }, {});

    const params = {
      currentPage: pagination.current,
      pageSize: pagination.pageSize,
      ...formValues,
      ...filters,
    };
    if (sorter.field) {
      params.sorter = `${sorter.field}_${sorter.order}`;
    }

    dispatch({
      type: 'sysRole/fetch',
      payload: params,
    });
  };

  handleFormReset = () => {
    const { form, dispatch } = this.props;
    form.resetFields();
    this.setState({
      formValues: {},
    });
    dispatch({
      type: 'sysRole/fetch',
      payload: {},
    });
  };

  deleteItem = id => {
    const { dispatch } = this.props;
    dispatch({
      type: 'sysRole/delete',
      payload: {
        id: id,
      },
    }).then(response => {
      if (response.message == 'success') {
        this.setState({
          selectedRows: [],
        });
        message.success(formatMessage({ id: 'app.common.delete-success' }));
      } else {
        message.warning(response.message);
      }
      dispatch({
        type: 'sysRole/fetch',
        payload: {},
      });
    });
  };

  handleDeleteClick = () => {
    const { selectedRows } = this.state;

    if (selectedRows.length === 0) {
      message.warning(formatMessage({ id: 'app.common.choose-delete' }));
      return;
    }

    Modal.confirm({
      title: formatMessage({ id: 'app.common.batch-delete' }),
      content: formatMessage({ id: 'app.common.confirm-batch-delete' }),
      okText: formatMessage({ id: 'app.common.confirm' }),
      cancelText: formatMessage({ id: 'app.common.cancel' }),
      onOk: () => this.deleteItem(selectedRows.map(row => row.id)),
    });
  };

  handleSelectRows = rows => {
    this.setState({
      selectedRows: rows,
    });
  };

  handleSearch = e => {
    if (e) {
      e.preventDefault();
    }
    const { dispatch, form } = this.props;
    form.validateFields((err, fieldsValue) => {
      if (err) return;
      const values = {
        ...fieldsValue,
      };
      this.setState({
        formValues: values,
      });
      dispatch({
        type: 'sysRole/fetch',
        payload: values,
      });
    });
  };

  handleModalVisible = flag => {
    this.setState({
      modalVisible: !!flag,
    });
  };

  handleUpdateModalVisible = (flag, record) => {
    this.setState({
      updateModalVisible: !!flag,
      updateFormValues: record || {},
    });
  };

  handleAuthorizeMenuFetch = record => {
    const { dispatch } = this.props;

    dispatch({
      type: 'sysRole/fetchMenuTree',
    }).then(() => {
      dispatch({
        type: 'sysRole/fetchCheckedMenu',
        payload: {
          roleId: record.id,
        },
      }).then(response => {

        this.handleAuthorizeMenuModalVisible(true, record);
      });
    });

  };

  handleAuthorizeMenuModalVisible = (flag, record) => {
    this.setState({
      authorizeMenuModalVisible: !!flag,
      updateFormValues: record || {},
    });
  };

  handleAuthorizeMenuButtonFetch = record => {
    const { dispatch } = this.props;
    dispatch({
      type: 'sysRole/fetchMenuButtonTree',
    }).then(() => {
      dispatch({
        type: 'sysRole/fetchCheckedMenuButton',
        payload: {
          roleCode: record.roleCode,
        },
      }).then(response => {
        this.handleAuthorizeButtonModalVisible(true, record);
      });
    });

  };

  handleAuthorizeButtonModalVisible = (flag, record) => {
    this.setState({
      authorizeMenuButtonModalVisible: !!flag,
      updateFormValues: record || {},
    });
  };

  handleExport = e => {
    e.preventDefault();
    const { dispatch, form } = this.props;
    form.validateFields((err, fieldsValue) => {
      if (err) return;
      const values = {
        ...fieldsValue,
      };
      this.setState({
        formValues: values,
      });
      dispatch({
        type: 'sysRole/export',
        payload: values,
      }).then(response => {
        saveAs(response, formatMessage({ id: 'app.sysrole.role-manage' }) + '.xlsx');
        dispatch({
          type: 'sysRole/fetch',
          payload: values,
        });
      });
    });
  };

  handleAdd = fields => {
    const { dispatch } = this.props;
    dispatch({
      type: 'sysRole/add',
      payload: {
        roleCode: fields.roleCode,
        roleName: fields.roleName,
        roleDescription: fields.roleDescription,
      },
    }).then(response => {
      if (response.message == 'success') {
        message.success(formatMessage({ id: 'app.common.add-success' }));
        this.handleModalVisible();
      } else {
        message.warning(response.message);
      }
      dispatch({
        type: 'sysRole/fetch',
        payload: {},
      });
    });
  };

  handleUpdate = fields => {
    const { dispatch } = this.props;
    dispatch({
      type: 'sysRole/update',
      payload: {
        body: {
          roleCode: fields.roleCode,
          roleName: fields.roleName,
          roleDescription: fields.roleDescription,
          id: fields.id,
        },
      },
    }).then(response => {
      if (response.message == 'success') {
        message.success(formatMessage({ id: 'app.common.edit-success' }));
        this.handleUpdateModalVisible();
      } else {
        message.warning(response.message);
      }
      dispatch({
        type: 'sysRole/fetch',
        payload: {},
      });
    });
  };

  handleAuthorizeMenu = (roleId, checkedMenuKeys) => {
    if (checkedMenuKeys.length === 0) {
      message.warning(formatMessage({ id: 'app.sysrole.authorize-required' }));
      return;
    }
    const { dispatch } = this.props;
    dispatch({
      type: 'sysRole/authorizeMenu',
      payload: {
        roleId: roleId,
        menuId: checkedMenuKeys,
      },
    }).then(response => {
      if (response.message == 'success') {
        message.success(formatMessage({ id: 'app.common.authorize-success' }));
        this.handleAuthorizeMenuModalVisible();
      } else {
        message.warning(response.message);
      }
      dispatch({
        type: 'sysRole/fetch',
        payload: {},
      });
    });
  };

  handleAuthorizeMenuButton = (roleCode, checkedMenuButtonKeys) => {
    const { dispatch } = this.props;
    dispatch({
      type: 'sysRole/authorizeMenuButton',
      payload: {
        roleCode: roleCode,
        menuButton: checkedMenuButtonKeys,
      },
    }).then(response => {
      if (response.message == 'success') {
        message.success(formatMessage({ id: 'app.common.authorize-success' }));
        this.handleAuthorizeButtonModalVisible();
      } else {
        message.warning(response.message);
      }
      dispatch({
        type: 'sysRole/fetch',
        payload: {},
      });
    });
  };

  renderSimpleForm() {
    const {
      form: { getFieldDecorator },
    } = this.props;
    return (
      <Form onSubmit={this.handleSearch} layout="inline">
        <Row gutter={{ md: 8, lg: 24, xl: 48 }}>
          <Col md={8} sm={24}>
            <FormItem label={formatMessage({ id: 'app.sysrole.role-name' })}>
              {getFieldDecorator('roleName')(
                <Input placeholder={formatMessage({ id: 'app.common.enter' })} />
              )}
            </FormItem>
          </Col>
          <Col md={8} sm={24}>
            <span className={styles.submitButtons}>
              <Button type="primary" htmlType="submit" icon="search">
                {formatMessage({ id: 'app.common.query' })}
              </Button>
              <Button
                style={{ marginLeft: 8 }}
                onClick={this.handleFormReset}
                type="primary"
                icon="reload"
              >
                {formatMessage({ id: 'app.common.reset' })}
              </Button>
            </span>
          </Col>
        </Row>
      </Form>
    );
  }

  renderForm() {
    return this.renderSimpleForm();
  }

  render() {
    const {
      sysRole: { data, menuTreeData, checkedMenuData, menuButtonTreeData, checkedMenuButtonData },
      loading,
    } = this.props;
    const {
      /**selectedRows,**/
      modalVisible,
      updateModalVisible,
      updateFormValues,
      authorizeMenuModalVisible,
      authorizeMenuButtonModalVisible,
    } = this.state;
    let menuData;
    if ({ menuTreeData }.menuTreeData) {
      menuData = { menuTreeData }.menuTreeData;
    }





    let checkedMenuKeys;

    if ({ checkedMenuData }.checkedMenuData) {
      checkedMenuKeys = { checkedMenuData }.checkedMenuData;
    }
    let menuButtonData;
    if ({ menuButtonTreeData }.menuButtonTreeData) {
      menuButtonData = { menuButtonTreeData }.menuButtonTreeData;
    }
    let checkedMenuButtonKeys;
    if ({ checkedMenuButtonData }.checkedMenuButtonData) {
      checkedMenuButtonKeys = { checkedMenuButtonData }.checkedMenuButtonData;
    }
    const parentMethods = {
      handleAdd: this.handleAdd,
      handleModalVisible: this.handleModalVisible,
    };
    const updateMethods = {
      handleUpdateModalVisible: this.handleUpdateModalVisible,
      handleUpdate: this.handleUpdate,
    };
    const authorizeMenuMethods = {
      handleAuthorizeMenuModalVisible: this.handleAuthorizeMenuModalVisible,
      handleAuthorizeMenu: this.handleAuthorizeMenu,
    };
    const authorizeMenuButtonMethods = {
      handleAuthorizeButtonModalVisible: this.handleAuthorizeButtonModalVisible,
      handleAuthorizeMenuButton: this.handleAuthorizeMenuButton,
    };
    const rowSelection = {
      onChange: (selectedRowKeys, selectedRows) => {
        this.handleSelectRows(selectedRows);
      },
    };


    return (
      <div>
        <Card bordered={false}>
          <div className={styles.tableList}>
            <div className={styles.tableListForm}>{this.renderForm()}</div>
            <div className={styles.tableListOperator}>
              {this.state.hiddenMenuButton.indexOf('sysrole:add') !== -1 ? null : (
                <Button icon="plus" type="primary" onClick={() => this.handleModalVisible(true)}>
                  {formatMessage({ id: 'app.common.add' })}
                </Button>
              )}
              {this.state.hiddenMenuButton.indexOf('sysrole:export') !== -1 ? null : (
                <Button icon="file-excel" type="primary" onClick={this.handleExport}>
                  {formatMessage({ id: 'app.common.export' })}
                </Button>
              )}
              {this.state.hiddenMenuButton.indexOf('sysrole:delete') !== -1 ? null : (
                <Button icon="delete" type="danger" ghost onClick={this.handleDeleteClick}>
                  {formatMessage({ id: 'app.common.batch-delete' })}
                </Button>
              )}
            </div>
            <ProTable
              bordered={true}
              search={false}
              rowKey={record => record.id}
              rowSelection={rowSelection}
              loading={loading}
              dataSource={data ? data.list : []}
              pagination={data ? data.pagination : {}}
              columns={this.columns}
              onChange={this.handleBasicTableChange}
              options={{
                density: true,
                reload: () => {
                  this.handleSearch();
                },
                fullScreen: true,
                setting: true,
              }}
            />
          </div>
        </Card>
        <CreateForm {...parentMethods} modalVisible={modalVisible} />
        {updateFormValues && Object.keys(updateFormValues).length ? (
          <UpdateForm
            {...updateMethods}
            updateModalVisible={updateModalVisible}
            values={updateFormValues}
          />
        ) : null}
        {updateFormValues && Object.keys(updateFormValues).length ? (
          <AuthorizeMenuForm
            {...authorizeMenuMethods}
            authorizeMenuModalVisible={authorizeMenuModalVisible}
            menuData={menuData}
            checkedMenuKeys={checkedMenuKeys}
            values={updateFormValues}
          />
        ) : null}
        {updateFormValues && Object.keys(updateFormValues).length ? (
          <AuthorizeMenuButtonForm
            {...authorizeMenuButtonMethods}
            authorizeMenuButtonModalVisible={authorizeMenuButtonModalVisible}
            menuButtonData={menuButtonData}
            checkedMenuButtonKeys={checkedMenuButtonKeys}
            values={updateFormValues}
          />
        ) : null}
      </div>
    );
  }
}

export default SysRole;
